﻿
Imports Microsoft.VisualBasic

Public Class Class1
    Public Shared Function sMin(Of T)(ByVal a As T, ByVal b As T) As T
        Return If(a < b, a, b)
    End Function
    'C++ TO VB CONVERTER TODO TASK: The original C++ template specifier was replaced with a VB generic specifier, which may not produce the same behavior:
    'ORIGINAL LINE: template<class T>
    Public Shared Function sMax(Of T)(ByVal a As T, ByVal b As T) As T
        Return If(a > b, a, b)
    End Function
    'C++ TO VB CONVERTER TODO TASK: The original C++ template specifier was replaced with a VB generic specifier, which may not produce the same behavior:
    'ORIGINAL LINE: template<class T>
    Public Shared Function sClamp(Of T)(ByVal x As T, ByVal min As T, ByVal max As T) As T
        Return GlobalMembersTinyplayer.sMax(min, GlobalMembersTinyplayer.sMin(max, x))
    End Function

    '***********************************************************************************
    '*                                                                                 *
    '* DirectSound output code                                                         *
    '*                                                                                 *
    '***********************************************************************************

    ' your rendering callback function has to look this way:
    ' parm: pointer you specified with dsInit
    ' buf: pointer to interleved stereo float destination buffer (1.0=0dB)
    ' len: length of buffer in samples (!)
	  typedef void(__stdcall DSIOCALLBACK)(Object* parm, Single *buf, UInteger len)

    ' initializes DirectSound output.
    ' callback: your render callback function
    ' parm: a pointer that'll be supplied to the function on every call
    ' hWnd: window handle of your application (GetForegroundWindow() works quite well :)
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: UInteger __stdcall dsInit(DSIOCALLBACK *callback, Object* parm, Object* hWnd);

    Function dsInit(ByVal callback As DSIOCALLBACK, ByVal parm As Object, ByVal hWnd As Object) As UInteger
    End Function
    ' shuts down DirectSound output
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: void __stdcall dsClose();

    Sub dsClose()
    End Sub
    ' gets sample-exact and latency compensated current play position
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: Integer __stdcall dsGetCurSmp();

    Function dsGetCurSmp() As Integer
    End Function
    ' sets player volume (default is 1.0)
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: void __stdcall dsSetVolume(Single vol);

    Sub dsSetVolume(ByVal vol As Single)
    End Sub
    ' forces rendering thread to update. On single-core CPUs it's a good idea to
    ' call this once per frame (improves A/V sync and reduces any stuttering), 
    ' with more than one CPU it's pretty much useless.
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: void __stdcall dsTick();

    Sub dsTick()
    End Sub

    ' lock and unlock the sound thread's thread sync lock. If you want to modify
    ' any of your sound variables outside the render thread, encapsulate that part
    ' of code in between these two functions.
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: void __stdcall dsLock();

    Sub dsLock()
    End Sub
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: void __stdcall dsUnlock();

    Sub dsUnlock()
    End Sub

    '***********************************************************************************
    '*                                                                                 *
    '* Synthesizer interface                                                           *
    '*                                                                                 *
    '***********************************************************************************

    ' returns size of work memory in bytes. Per synthesizer instance reserve at least
    ' this amount of memory and supply it as the "pthis" parameter of all other functions
    ' Note: If you need only one static instance, 3 Megabytes are a good bet.
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: UInteger __stdcall synthGetSize();

    Function synthGetSize() As UInteger
    End Function
    ' inits synthesizer instance.
    ' pthis     : pointer to work mem
    ' patchmap  : pointer to patch data
    ' samplerate: output sample rate (44100-192000 Hz), use 44100 when playing with dsio
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: void __stdcall synthInit(Object* pthis, const Object* patchmap, Integer samplerate=44100);

    Sub synthInit(ByVal pthis As Object, ByVal patchmap As Object, Optional ByVal samplerate As Integer = 44100)
    End Sub
    ' inits global parameters
    ' pthis: pointer to work mem
    ' ptr  : pointer to global parameters
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: void __stdcall synthSetGlobals(Object* pthis, const Object* ptr);

    Sub synthSetGlobals(ByVal pthis As Object, ByVal ptr As Object)
    End Sub

    ' inits speech synthesizer texts
    ' pthis: pointer to work mem
    ' ptr  : pointer to text array
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: void __stdcall synthSetLyrics(Object* pthis, String *ptr);

    Sub synthSetLyrics(ByVal pthis As Object, ByVal ptr As String)
    End Sub

    ' renders synth output to destination buffer
    ' pthis: pointer to work mem
    ' buf  : pointer to interleaved float stereo out buffer
    ' smp  : number of samples to render
    ' buf2 : if this is specified, the synth will render the left and right channel into
    '        two mono float buffers at buf and buf2 instead of one interleaved buffer
    ' add  : if this is specified, the synth will add its output to the destination
    '        buffer instead of replacing its contents
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: void __stdcall synthRender(Object* pthis, Object* buf, Integer smp, Object* buf2=0, Integer add=0);

    Sub synthRender(ByVal pthis As Object, ByVal buf As Object, ByVal smp As Integer, Optional ByVal buf2 As Object = 0, Optional ByVal add As Integer = 0)
    End Sub

    ' pipes a stream of MIDI commands to the synthesizer
    ' pthis: pointer to work mem
    ' ptr  : pointer to buffer with MIDI data to process.
    '        NOTE: The buffer MUST end with a 0xfd byte
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: void __stdcall synthProcessMIDI(Object* pthis, const Object* ptr);

    Sub synthProcessMIDI(ByVal pthis As Object, ByVal ptr As Object)
    End Sub

    ' sets operation mode of VU meters
    ' pthis: pointer to work mem
    ' mode : 0 for peak meters, 1 for RMS meters
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: void __stdcall synthSetVUMode(Object* pthis, Integer mode);

    Sub synthSetVUMode(ByVal pthis As Object, ByVal mode As Integer) ' 0: peak, 1: rms
    End Sub

    ' retrieves VU meter data for a channel
    ' pthis: pointer to work mem
    ' ch   : channel to retrieve (0..15)
    ' l    : pointer to float variable where left VU is stored
    ' r    : pointer to float variable where right VU is stored
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: void __stdcall synthGetChannelVU(Object* pthis, Integer ch, Single *l, Single *r);

    Sub synthGetChannelVU(ByVal pthis As Object, ByVal ch As Integer, ByRef l As Single, ByRef r As Single) ' ch: 0..15
    End Sub

    ' retrieves master VU meter
    ' pthis: pointer to work mem
    ' l    : pointer to float variable where left VU is stored
    ' r    : pointer to float variable where right VU is stored
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: void __stdcall synthGetMainVU(Object* pthis, Single *l, Single *r);

    Sub synthGetMainVU(ByVal pthis As Object, ByRef l As Single, ByRef r As Single)
    End Sub

#If __cplusplus Then
#End If



    Friend Shared stdout As System.IntPtr
    Friend Shared player As New V2MPlayer()

    Public Shared Sub print(ByVal bla As String)
        Dim bw As UInteger
        Dim len As Integer = -1
        len += 1
        Do While bla.Chars(len)

            len += 1
        Loop
        WriteFile(stdout, bla, len, bw, 0)
    End Sub

    '//////////////////////////////////////////////////////////////////////////////////////////////////

    'C++ TO VB CONVERTER NOTE: 'extern' variable declarations are not required in VB:
    extern "C" const Byte theTune[]

#If NDEBUG Then
	Public Shared Sub mainCRTStartup()
#Else
    Shared Sub Main()
#End If
        stdout = GetStdHandle(STD_OUTPUT_HANDLE)

        GlobalMembersTinyplayer.print(vbLf & "Farbrausch Tiny Music Player v0.dontcare TWO" & vbLf)
        GlobalMembersTinyplayer.print("Code and Synthesizer (C) 2000-2008 kb/Farbrausch" & vbLf)
        GlobalMembersTinyplayer.print(vbLf & vbLf & "Now Playing: 'Patient Zero' by Melwyn & Little Bitchard" & vbLf)

        player.Init()
        player.Open(theTune)

        dsInit(player.RenderProxy, player, GetForegroundWindow())

        player.Play()

        Dim startTicks As Integer = GetTickCount()

        GlobalMembersTinyplayer.print(vbLf & vbLf & "press ESC to quit" & vbLf)
        Do While GetAsyncKeyState(VK_ESCAPE) >= 0
            Sleep(10)
        Loop

        dsClose()
        player.Close()
        ExitProcess(0)
    End Sub
End Class

'***********************************************************************************
'***********************************************************************************
'*                                                                                 *
'*  Tinyplayer - TibV2 example                                                     *
'*  written by Tammo 'kb' Hinrichs 2000-2008                                       *
'*  This file is in the public domain                                              *
'*  "Patient Zero" is (C) Melwyn+LB 2005, do not redistribute                      *
'*                                                                                 *
'***********************************************************************************
'***********************************************************************************

'C++ TO VB CONVERTER NOTE: The following #define macro was replaced in-line:
'ORIGINAL LINE: #define WIN32_LEAN_AND_MEAN
#Const WIN32_LEAN_AND_MEAN = True

'***********************************************************************************
'***********************************************************************************
'*                                                                                 *
'*  V2 module player (.v2m)                                                        *
'*  (c) Tammo 'kb' Hinrichs 2000-2008                                              *
'*  This file is under the Artistic License 2.0, see LICENSE.txt for details       *
'*                                                                                 *
'***********************************************************************************
'***********************************************************************************


'***********************************************************************************
'*                                                                                 *
'*  Type definitions                                                               *
'*                                                                                 *
'***********************************************************************************






#Const sTRUE = True
#Const sFALSE = True

'C++ TO VB CONVERTER TODO TASK: The original C++ template specifier was replaced with a VB generic specifier, which may not produce the same behavior:
'ORIGINAL LINE: template<class T>



'***********************************************************************************
'*                                                                                 *
'*  V2M player class                                                               *
'*                                                                                 *
'***********************************************************************************

Public Class V2MPlayer

    ' init
    ' call this instead of a constructor
    Public Sub Init(Optional ByVal a_tickspersec As UInteger = 1000)
        m_tpc = a_tickspersec
        m_base.valid = 0
    End Sub



    ' opens a v2m file for playing
    '
    ' a_v2mptr			: ptr to v2m data
    '								NOTE: the memory block has to remain valid
    '								as long as the player is opened!
    ' a_samplerate : samplerate at which the synth is operating
    '                if this is zero, output will be disabled and
    '                only the timing query functions will work

    ' returns  : flag if succeeded
    '
    Function Open(ByVal a_v2mptr As Object, Optional ByVal a_samplerate As UInteger = 44100) As Integer
    End Function
    ' closes player
    '
    Sub Close()
    End Sub


    ' starts playing
    '
    ' a_time   : time offset from song start in msecs
    '
    Sub Play(Optional ByVal a_time As UInteger = 0)
    End Sub


    ' stops playing
    '
    ' a_fadetime : optional fade out time in msecs
    '
Sub @Stop(Optional ByVal a_fadetime As UInteger = 0)
    End Sub



    ' render call (to be used from sound thread et al)
    ' renders samples (or silence if not playing) into buffer
    '
    ' a_buffer : ptr to stereo float sample buffer (0dB=1.0f)
    ' a_len    : number of samples to render
    ' 
    ' returns  : flag if playing
    '

    Sub Render(ByRef a_buffer As Single, ByVal a_len As UInteger, Optional ByVal a_add As Integer = 0)
    End Sub



    ' render proxy for C-style callbacks
    ' 
    ' a_this   : void ptr to instance
    ' rest as in Render()
    '
    'C++ TO VB CONVERTER NOTE: __stdcall is not available in VB:
    'ORIGINAL LINE: static void __stdcall RenderProxy(Object* a_this, Single *a_buffer, UInteger a_len)
    Public Shared Sub RenderProxy(ByVal a_this As Object, ByRef a_buffer As Single, ByVal a_len As UInteger)
        'C++ TO VB CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in VB:
		reinterpret_cast<V2MPlayer*>(a_this).Render(a_buffer,a_len)
    End Sub

    ' returns if song is currently playing
    Function IsPlaying() As Integer
    End Function

#If V2MPLAYER_SYNC_FUNCTIONS Then

	' Retrieves an array of timer<->song position 
	'
	' a_dest: pointer to a variable which will receive the address of an array of long
	'         values structured as following:
	'         first  long: time in ms
	'         second long: song position (see above for a description)
	'											format: 0xBBBBTTNN, where
	'															BBBB is the bar number (starting at 0)
	'															TT   is the number of the 32th tick within the current bar
	'															NN   is the total number of 32th ticks a the current bar has 
	'													         (32, normally, may change with different time signatures than 4/4)
	'         ... and so on for every found position
	'
	' NOTE: it is your responsibility to free the array again.
	'
	' returns: number of found song positions
	'
    Function CalcPositions(ByVal a_dest[] As Integer) As UInteger
    End Function


#End If


    ' ------------------------------------------------------------------------------------------------------
    '  no need to look beyond this point.
    ' ------------------------------------------------------------------------------------------------------


    ' struct defs

    ' General info from V2M file
    Private Class V2MBase
        Public valid As Integer
        Public patchmap As String
        Public globals As String
        Public timediv As UInteger
        Public timediv2 As UInteger
        Public maxtime As UInteger
        Public gptr As String
        Public gdnum As UInteger
        Public Class Channel
            Public notenum As UInteger
            Public noteptr As String
            Public pcnum As UInteger
            Public pcptr As String
            Public pbnum As UInteger
            Public pbptr As String
            Public Class CC
                Public ccnum As UInteger
                Public ccptr As String
            End Class
            Public ctl(6) As CC
        End Class
        Public chan(15) As Channel
        Public speechdata As String
        Public speechptrs(255) As String
    End Class


    ' player state
    Private Class PlayerState
        'C++ TO VB CONVERTER NOTE: Enums must be named in VB, so the following enum has been named AnonymousEnum:
        Public Enum AnonymousEnum
            [OFF]
            STOPPED
            PLAYING
        End Enum
        Public state As AnonymousEnum
        Public time As UInteger
        Public nexttime As UInteger
        Public gptr As String
        Public gnt As UInteger
        Public gnr As UInteger
        Public usecs As UInteger
        Public num As UInteger
        Public den As UInteger
        Public tpq As UInteger
        Public bar As UInteger
        Public beat As UInteger
        Public tick As UInteger
        Public Class Channel
            Public noteptr As String
            Public notenr As UInteger
            Public notent As UInteger
            Public lastnte As Byte
            Public lastvel As Byte
            Public pcptr As String
            Public pcnr As UInteger
            Public pcnt As UInteger
            Public lastpc As Byte
            Public pbptr As String
            Public pbnr As UInteger
            Public pbnt As UInteger
            Public lastpb0 As Byte
            Public lastpb1 As Byte
            Public Class CC
                Public ccptr As String
                Public ccnt As UInteger
                Public ccnr As UInteger
                Public lastcc As Byte
            End Class
            Public ctl(6) As CC
        End Class
        Public chan(15) As Channel
        Public cursmpl As UInteger
        Public smpldelta As UInteger
        Public smplrem As UInteger
        Public tdif As UInteger
    End Class

    ' \o/
    Private m_synth(3 * 1024 * 1024 - 1) As Byte ' TODO: keep me uptodate or use "new"

    ' member variables
    Private m_tpc As UInteger
    Private m_base As New V2MBase()
    Private m_state As New PlayerState()
    Private m_samplerate As UInteger
    Private m_timeoffset As Integer
    Private m_midibuf(4095) As Byte
    Private m_fadeval As Single
    Private m_fadedelta As Single

    ' internal methods

    Function InitBase(ByVal a_v2m As Object) As Integer ' inits base struct from v2m
    End Function

    Sub Reset() ' resets player, inits synth
    End Sub

    Sub Tick() ' one midi player tick
    End Sub

End Class

'***********************************************************************************
'***********************************************************************************
'*                                                                                 *
'*  LibV2 header file                                                              *
'*  written by Tammo 'kb' Hinrichs 2000-2008                                       *
'*  This file is in the public domain                                              *
'*                                                                                 *
'***********************************************************************************
'***********************************************************************************


#If __cplusplus Then
'C++ TO VB CONVERTER TODO TASK: Extern blocks are not supported in VB.
extern "C"
#End If


Partial Friend NotInheritable Class DefineConstants
    Public Const sTRUE As Integer = 1
    Public Const sFALSE As Integer = 0
End Class

